package cn.edu.ncepu;

import java.util.ArrayList;
import java.util.List;

/**
 * 霍纳多项式类（模拟Python版本的HornerPolynomial）
 * 系数存储：polynomial[0] 为最高次项系数，polynomial[n] 为常数项
 * 例如：x² + 1 → [1.0, 0.0, 1.0]
 */
public class HornerPolynomial {
    private final List<Double> polynomial;

    public HornerPolynomial(List<Double> polynomial) {
        this.polynomial = new ArrayList<>(polynomial);
    }

    /**
     * 霍纳法则求值：计算多项式在x处的值
     * @param x 自变量值
     * @return 多项式值
     */
    public double apply(double x) {
        double result = 0.0;
        for (double coeff : polynomial) {
            result = result * x + coeff;
        }
        return result;
    }

    /**
     * 格式化输出多项式字符串（如 x² + 1）
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        int degree = polynomial.size() - 1; // 最高次项次数
        boolean firstTerm = true;

        for (int i = 0; i < polynomial.size(); i++) {
            double coeff = polynomial.get(i);
            if (Math.abs(coeff) < 1e-15) { // 忽略0系数
                continue;
            }

            // 处理符号
            if (!firstTerm) {
                sb.append(coeff > 0 ? " + " : " - ");
                coeff = Math.abs(coeff);
            } else {
                firstTerm = false;
                if (coeff < 0) {
                    sb.append("-");
                    coeff = Math.abs(coeff);
                }
            }

            // 处理系数
            int currentDegree = degree - i;
            if (currentDegree == 0) { // 常数项
                sb.append(coeff);
            } else {
                if (Math.abs(coeff) != 1.0) {
                    sb.append(coeff);
                }
                // 处理x的幂次
                sb.append("x");
                if (currentDegree > 1) {
                    sb.append("**").append(currentDegree);
                }
            }
        }

        return sb.isEmpty() ? "0" : sb.toString();
    }

    // 获取多项式系数
    public List<Double> getPolynomial() {
        return new ArrayList<>(polynomial);
    }
}